home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / unzip42.zip / MATCH.C < prev    next >
C/C++ Source or Header  |  1992-03-14  |  5KB  |  202 lines

  1. /*--------------------------------------------------------------------------
  2.  
  3.   match.c
  4.  
  5.   The match() routine recursively compares a string to a "pattern" (regular
  6.   expression), returning TRUE if a match is found or FALSE if not.  This
  7.   version is specifically for use with unzip.c:  it leaves the case (upper,
  8.   lower, or mixed) of the string alone, but converts any uppercase characters
  9.   in the pattern to lowercase if indicated by the global var pInfo->lcflag
  10.   (which is to say, string is assumed to have been converted to lowercase
  11.   already, if such was necessary).
  12.  
  13.   --------------------------------------------------------------------------
  14.  
  15.   Copyrights:  see accompanying file "COPYING" in UnZip source distribution.
  16.  
  17.   --------------------------------------------------------------------------*/
  18.  
  19.  
  20. #include "unzip.h"
  21.  
  22.  
  23. /*******************/
  24. /*  Match Defines  */
  25. /*******************/
  26.  
  27. #define ASTERISK        '*'     /* The '*' metacharacter */
  28. #define QUESTION        '?'     /* The '?' metacharacter */
  29. #define BACK_SLASH      '\\'    /* The '\' metacharacter */
  30. #define LEFT_BRACKET    '['     /* The '[' metacharacter */
  31. #define RIGHT_BRACKET   ']'     /* The ']' metacharacter */
  32. #define EOS             '\000'  /* end-of-string */
  33.  
  34. #define IS_OCTAL(ch)    (ch >= '0' && ch <= '7')
  35.  
  36.  
  37.  
  38. /********************/
  39. /*  Match Typedefs  */
  40. /********************/
  41.  
  42. typedef short int BOOLEAN;
  43.  
  44.  
  45.  
  46. /*************************************/
  47. /*  Match Local Function Prototypes  */
  48. /*************************************/
  49.  
  50. static BOOLEAN do_list __((register char *string, char *pattern));
  51. static void list_parse __((char **patp, char *lowp, char *highp));
  52. static char nextch __((char **patp));
  53.  
  54.  
  55.  
  56.  
  57.  
  58. /**********************/
  59. /*  Function match()  */
  60. /**********************/
  61.  
  62. int match(string, pattern)
  63. char *string;
  64. char *pattern;
  65. {
  66.     register int ismatch;
  67.  
  68.     ismatch = FALSE;
  69.     switch (*pattern) {
  70.     case ASTERISK:
  71.         pattern++;
  72.         do {
  73.             ismatch = match(string, pattern);
  74.         }
  75.         while (!ismatch && *string++ != EOS);
  76.         break;
  77.     case QUESTION:
  78.         if (*string != EOS)
  79.             ismatch = match(++string, ++pattern);
  80.         break;
  81.     case EOS:
  82.         if (*string == EOS)
  83.             ismatch = TRUE;
  84.         break;
  85.     case LEFT_BRACKET:
  86.         if (*string != EOS)
  87.             ismatch = do_list(string, pattern);
  88.         break;
  89.     case BACK_SLASH:
  90.         pattern++;
  91.     default:
  92.         if (*string == ((pInfo->lcflag && isupper(*pattern))?
  93.             tolower(*pattern) : *pattern)) {
  94.             string++;
  95.             pattern++;
  96.             ismatch = match(string, pattern);
  97.         } else
  98.             ismatch = FALSE;
  99.         break;
  100.     }
  101.     return (ismatch);
  102. }
  103.  
  104.  
  105.  
  106.  
  107.  
  108. /************************/
  109. /*  Function do_list()  */
  110. /************************/
  111.  
  112. static BOOLEAN do_list(string, pattern)
  113. register char *string;
  114. char *pattern;
  115. {
  116.     register BOOLEAN ismatch;
  117.     register BOOLEAN if_found;
  118.     register BOOLEAN if_not_found;
  119.     auto char lower;
  120.     auto char upper;
  121.  
  122.     pattern++;
  123.     if (*pattern == '!') {
  124.         if_found = FALSE;
  125.         if_not_found = TRUE;
  126.         pattern++;
  127.     } else {
  128.         if_found = TRUE;
  129.         if_not_found = FALSE;
  130.     }
  131.     ismatch = if_not_found;
  132.     while (*pattern != ']' && *pattern != EOS) {
  133.         list_parse(&pattern, &lower, &upper);
  134.         if (*string >= lower && *string <= upper) {
  135.             ismatch = if_found;
  136.             while (*pattern != ']' && *pattern != EOS)
  137.                 pattern++;
  138.         }
  139.     }
  140.  
  141.     if (*pattern++ != ']') {
  142.         printf("Character class error\n");
  143.         exit(1);
  144.     } else if (ismatch)
  145.         ismatch = match(++string, pattern);
  146.  
  147.     return (ismatch);
  148. }
  149.  
  150.  
  151.  
  152.  
  153.  
  154. /***************************/
  155. /*  Function list_parse()  */
  156. /***************************/
  157.  
  158. static void list_parse(patp, lowp, highp)
  159. char **patp;
  160. char *lowp;
  161. char *highp;
  162. {
  163.     *lowp = nextch(patp);
  164.     if (**patp == '-') {
  165.         (*patp)++;
  166.         *highp = nextch(patp);
  167.     } else
  168.         *highp = *lowp;
  169. }
  170.  
  171.  
  172.  
  173.  
  174.  
  175. /***********************/
  176. /*  Function nextch()  */
  177. /***********************/
  178.  
  179. static char nextch(patp)
  180. char **patp;
  181. {
  182.     register char ch;
  183.     register char chsum;
  184.     register int count;
  185.  
  186.     ch = *(*patp)++;
  187.     if (ch == '\\') {
  188.         ch = *(*patp)++;
  189.         if (IS_OCTAL(ch)) {
  190.             chsum = 0;
  191.             for (count = 0; count < 3 && IS_OCTAL(ch); count++) {
  192.                 chsum *= 8;
  193.                 chsum += ch - '0';
  194.                 ch = *(*patp)++;
  195.             }
  196.             (*patp)--;
  197.             ch = chsum;
  198.         }
  199.     }
  200.     return (ch);
  201. }
  202.